﻿using _698._45Tool.Utils;
using CommonServiceLocator;
using Communication;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Jn698._45GWTool.Communication;
using Jn698._45GWTool.Models;
using Jn698._45GWTool.ServiceReference1;
using Jn698._45GWTool.Settings;
using Jn698._45GWTool.Utils;
using Jn698._45GWTool.ViewModels;
using Jn698._45GWTool.ViewModels.Controls;
using Jn698._45GWTool.ViewModels.Controls.DataControls;
using Jn698._45GWTool.Views;
using Jn698._45Tool.Service;
using Jn698._45Tool.Utils;
using nblTool.utils;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using TouchSocket.Core;
using TouchSocket.Sockets;
using WebFirst.Entities;
using WindowsFormsApp1.Utils;

namespace Jn698._45GWTool.ViewModels
{
    public class MainViewModel:ViewModelBase
    {
        #region 字段
        private SerialPortHelper serialPortHelper = SerialPortHelper.Instance;
        private TcpHelper tcpHelper = TcpHelper.Instance;
        private DeviceService deviceService = new DeviceService();
        public static Device selectedDevice;
        //public static bool State = false;
        private SolidColorBrush backColor;
        public StateGridClient sc;
        public static int TopIndex=0;
        #endregion
        #region 属性

        private int selectedTop;

        public int SelectedTop
        {
            get { return selectedTop; }
            set
            {
                if (Set(ref selectedTop,value))
                {
                    TopIndex = value;
                    if (TopIndex==4)
                    {
                        ServiceLocator.Current.GetInstance<PlanSetViewModel>().SelectedPlanSet = 0;
                    }
                    else if(TopIndex==0)
                    {
                        ServiceLocator.Current.GetInstance<AppControlViewModel>().ListBoxType = 0;
                    }
                } 
            }
        }

        public SolidColorBrush BackColor
        {
            get { return backColor; }
            set { backColor = value; RaisePropertyChanged(); }
        }
        private string tbCommSate;

        public string TbCommSate
        {
            get { return tbCommSate; }
            set { tbCommSate = value; RaisePropertyChanged(); }
        }

        public Device SelectedDevice
        {
            get { return selectedDevice; }
            set { selectedDevice = value; RaisePropertyChanged(); GetFrameAddress(); }
        }

        private int selectedIndex;

        public int SelectedIndex
        {
            get { return selectedIndex; }
            set { selectedIndex = value;RaisePropertyChanged(); }
        }

        private ObservableCollection<Device> deviceList;

        public ObservableCollection<Device> DeviceList
        {
            get 
            {
                if (deviceList == null)
                {
                    deviceList = new ObservableCollection<Device>(deviceService.Select());
                }
                return deviceList; 
            }
            set { deviceList = value; }
        }

        private ObservableCollection<string> securityDataList;

        public ObservableCollection<string> SecurityDataList
        {
            get { return securityDataList; }
            set { Set(ref securityDataList, value); }
        }

        private int securitySelectedIndex;

        public int SecuritySelectedIndex
        {
            get { return securitySelectedIndex; }
            set { Set(ref securitySelectedIndex, value); }
        }

        public static bool state;

        public bool State
        {
            get { return state; }
            set { Set(ref state, value); }
        }

        private bool connctFlag;

        public bool ConnectFlag
        {
            get { return connctFlag; }
            set { Set(ref connctFlag,value); }
        }



        private bool? btnOpenCommFlag;

        public bool? BtnOpenCommFlag
        {
            get { if (btnOpenCommFlag == null) BtnOpenCommFlag = true; return btnOpenCommFlag; }
            set { btnOpenCommFlag = value; RaisePropertyChanged(); }
        }

        private bool? btnCloeseCommFlag;

        public bool? BtnCloseCommFlag
        {
            get { if (btnCloeseCommFlag == null) BtnCloseCommFlag = false;  return btnCloeseCommFlag; }
            set { btnCloeseCommFlag = value;  RaisePropertyChanged(); }
        }

        /// <summary>
        /// 构造器
        /// </summary>
        public MainViewModel()
        {
            serialPortHelper.ReceiveDataEvent += ReceiveDataEvent;
            tcpHelper.ReceiveDataEvent += ReceiveDataEvent;
            SecurityDataList = new ObservableCollection<string>() { "0-纯明文操作", "1-明文+RN", "2-明文+RN_MAC", "3-明文+SID_MAC", "4-密文+SID", "5-密文+SID_MAC" };
            SelectedTop = 0;
            
            try
            {
                
                /*Config config = XmlHelper.Deserializer<Config>("Config.xml");
                if (config != null)
                {
                    System.ServiceModel.Channels.Binding binding = new NetTcpBinding(SecurityMode.None, true);
                    //EndpointAddress endpoint = new EndpointAddress("net.tcp://10.1.2.32:10010/StateGrid/");
                    //EndpointAddress endpoint = new EndpointAddress(config.EndpointAddress);
                    EndpointAddress endpoint = new EndpointAddress(EncryptorSettings.Instanse.EndpointAddress);
                    sc = new StateGridClient(binding, endpoint);
                }
                else
                {
                    MessageBox.Show("获取加密机服务地址错误,请检查配置文件是否正确");
                }*/
                System.ServiceModel.Channels.Binding binding = new NetTcpBinding(SecurityMode.None, true);
                //EndpointAddress endpoint = new EndpointAddress("net.tcp://10.1.2.32:10010/StateGrid/");
                //EndpointAddress endpoint = new EndpointAddress(config.EndpointAddress);
                EndpointAddress endpoint = new EndpointAddress(EncryptorSettings.Instanse.EndpointAddress);
                sc = new StateGridClient(binding, endpoint);
            }
            catch (Exception e)
            {
                MessageBox.Show("获取加密机服务地址错误,请检查地址是否正确"+e.Message);
                
            }

        }
        #endregion


        #region 方法
        private void ReceiveDataEvent(object sender, EventArgs e)
        {
            var arg = e as ReceiveDataEventArg;
            //在窗体上显示接收到的报文
            /*string msgStr = "";
            for (int i = 0; i < arg.Data.Length; i++)
            {
                msgStr += arg.Data[i].ToString("X2") + " ";
            }*/
            try
            {
                Messenger.Default.Send<string>($"接收帧({DateTime.Now.ToString()})：{string.Join(" ", arg.Data.Select(x => x.ToString("X2")))}", "RecvMessage");
                Messenger.Default.Send<string>(AnalysisMessage.AnalysisAPDU(arg.Data, 14), "AnalyMessage");
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            

        }
        private void SetCommOpenFlag(bool flag)
        {
            BtnOpenCommFlag = !flag;
            BtnCloseCommFlag = flag;
        }
        private void OpenComm()
        {
            switch (CommViewModel.selectedCommType)
            {
                case "串口":
                    serialPortHelper.Open();
                    if (serialPortHelper.Status)
                    {
                        State = true;
                        SetCommOpenFlag(State);
                        BackColor = Brushes.LightGreen;
                        TbCommSate = $"串口{serialPortHelper.serialPortName}已打开！";
                    }
                    else
                    {
                        State = false;
                        SetCommOpenFlag(State);
                        TbCommSate = $"串口{serialPortHelper.serialPortName}关闭！";
                    }
                    break;
                case "GPRS":
                    tcpHelper.OpenTCP();
                    if (tcpHelper.Status==ServerState.Running)
                    {
                        State = true;
                        SetCommOpenFlag(State);
                        TbCommSate = $"通道GPRS:{tcpHelper.Host}已打开！";
                    }
                    else
                    {
                        State = false;
                        SetCommOpenFlag(State);
                        TbCommSate = $"通道GPRS:{tcpHelper.Host}关闭！";
                    }
                    break;
                default:
                    break;
            }
        }
        private void AddDeviceAddress(Device d)
        {
            try
            {
                if (deviceService.Insert(d) > 0)
                {
                    
                    DeviceList.Add(d);
                    Console.WriteLine("增加电表成功");
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show($"增加电表失败:{e1.Message}");
                
            }

        }

        private void DelectDeviceAddress(Device d)
        {
            try
            {
                if (deviceService.Delete(d) > 0)
                {
                    DeviceList.Remove(d);
                    Console.WriteLine("删除电表成功");
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show($"删除电表失败:{e1.Message}");

            }
        }

        private void GetFrameAddress()
        {
            List<byte> addTemp = new List<byte>();
            if (selectedDevice == null)
            {
                return;
            }
            byte[] byteAddress = StringUtils.strToHexByte(selectedDevice.DeviceAddress);
            addTemp.Add((byte)(byteAddress.Length - 1));
            Array.Reverse(byteAddress);
            addTemp.AddRange(byteAddress);
            addTemp.Add(0x11);
            ServiceLocator.Current.GetInstance<CommonControlViewModel>().FrameAddress= ByteUtils.bytesToHexString(addTemp.ToArray());
        }
        #endregion
        #region command
        public RelayCommand SetCommCommand
        {
            get
            {
                var command = new RelayCommand(() => {
                    //Messenger.Default.Register<string>(this, "CommWindowResult", (s) => { Console.WriteLine(s); });
                    CommWindow commWindow = new CommWindow();
                    if (commWindow.ShowDialog()==true)
                    {
                        OpenComm();
                    }
                    
                    //Messenger.Default.Unregister<string>(this, "CommWindowResult");
                });
                return command;
            }
        }
        public RelayCommand OpenCommCommand
        {
            get
            {
                var command = new RelayCommand(() => { OpenComm(); });
                return command;
            }
        }
        public RelayCommand CloseCommCommand
        {
            get
            {
                var command = new RelayCommand(() => {
                    State = false;
                    switch (CommViewModel.selectedCommType)
                    {
                        case "串口":
                            serialPortHelper.Close();
                            SetCommOpenFlag(State);
                            BackColor = Brushes.Transparent;
                            TbCommSate = $"串口{serialPortHelper.serialPortName}关闭！";
                            break;
                        case "GPRS":
                            tcpHelper.CloseTCP();
                            SetCommOpenFlag(State);
                            TbCommSate = $"通道GPRS:{tcpHelper.Host}关闭！";
                            break;
                        default:
                            break;
                    }
                });
                return command;
            }
        }
        private readonly byte[] CRC8Tbl = new byte[16]
    {
        0, 49, 98, 83, 196, 245, 166, 151, 185, 136,
        219, 234, 125, 76, 31, 46
    };
        public byte crc(byte crc, byte[] buf)
        {
            foreach (byte b in buf)
            {
                byte b2 = (byte)(crc >> 4);
                crc <<= 4;
                crc ^= CRC8Tbl[b2 ^ (b >> 4)];
                b2 = (byte)(crc >> 4);
                crc <<= 4;
                crc ^= CRC8Tbl[b2 ^ (b & 0xF)];
            }
            return crc;
        }
        public RelayCommand<string> AddAddressCommand
        {
            get
            {
                var command = new RelayCommand<string>((address) => {

                    
                    Device device = new Device();
                    device.DeviceType = "电表";
                    device.DeviceAddress = address.PadLeft(12, '0'); ;
                    AddDeviceAddress(device);
                   
                });
                return command;
            }
        }
        

        public RelayCommand DelectSelectedsDeviceCommand
        {
            get
            {
                var command = new RelayCommand(() =>
                {
                    
                    for (int i = DeviceList.Count - 1; i >= 0; i--)
                    {
                        Device device = DeviceList[i];
                        //Console.WriteLine(device.IsSelected);
                       
                        if (device.IsSelected)
                        {
                            DelectDeviceAddress(device);
                        }
                    }
                });
                return command;
            }
        }

        public RelayCommand DelectAllDeviceCommand
        {
            get
            {
                var command = new RelayCommand(() =>
                {
                    
                    deviceService.DeleteAll();
                    DeviceList.Clear();
                });
                return command;
            }
        }
        public RelayCommand RichTextBoxSelectionChangedCommand
        {
            get
            {
                var command = new RelayCommand(() =>
                {
                    var richTextBox = Keyboard.FocusedElement as RichTextBox;
                    if (richTextBox != null)
                    {
                        // 获取选择的文本
                        string selectedText = richTextBox.Selection.Text;

                        // 处理选择的文本
                        // ...
                    }
                });
                return command;
            }
        }
        #endregion
    }
}
